package cn.lingyangwl.agile.auth.third;

import cn.lingyangwl.agile.auth.model.rqrs.third.AuthUrlGetReq;
import cn.lingyangwl.agile.auth.model.rqrs.third.ThirdAuthResp;
import cn.lingyangwl.agile.auth.model.rqrs.third.ThirdAuthUser;
import cn.lingyangwl.agile.auth.model.rqrs.third.ThirdLoginReq;
import cn.lingyangwl.agile.auth.oauth2.model.RegisteredClient;
import cn.lingyangwl.agile.model.enums.ConfigDefineEnum;
import cn.lingyangwl.agile.model.module.auth.GrantTypeEnum;
import cn.lingyangwl.agile.model.module.config.ConfigInfo;
import cn.lingyangwl.agile.model.module.config.param.BaseConfigParam;
import cn.lingyangwl.agile.model.module.config.param.GiteeParam;
import cn.lingyangwl.framework.tool.core.exception.Assert;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.enums.scope.AuthGiteeScope;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthScopeUtils;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.stereotype.Component;

/**
 * gitee社交授权
 *
 * @author shenguangyang
 */
@Slf4j
@Component
public class GiteeAuth extends BaseThirdAuth {
    @Override
    public GrantTypeEnum grantType() {
        return GrantTypeEnum.GITEE;
    }

    private AuthRequest getAuthRequest(RegisteredClient client, String backUrl) {
        ConfigInfo config = configFactory.getConfigOfNonNull(ConfigDefineEnum.GITEE);
        GiteeParam param = BaseConfigParam.jsonToObject(config.getConfigKey(), config.getConfigValue());

        String redirectUri = getThirdRedirectUri(param.getCallbackUrl(), backUrl, client);
        return new AuthGiteeRequest(AuthConfig.builder()
                .clientId(param.getClientId())
                .clientSecret(param.getClientSecret())
                .redirectUri(redirectUri)
                .scopes(AuthScopeUtils.getScopes(AuthGiteeScope.USER_INFO))
                .build());
    }

    @Override
    public ThirdAuthUser doLogin(ThirdLoginReq req) {
        Assert.notEmpty(req.getBackUrl(), "backUrl不能为空");
        AuthCallback callbackReq = thirdAssembly.toAuthCallback(req);

        @SuppressWarnings("unchecked")
        AuthResponse<AuthUser> login = getAuthRequest(req.getClient(), req.getBackUrl()).login(callbackReq);

        if (!login.ok()) {
            log.error("third login: {}", login.getMsg());
            throw new BizException("三方授权失败, 请重新发起登录");
        }

        return thirdAssembly.toThirdAuthUser(login.getData());
    }

    @Override
    public ThirdAuthResp doAuthorize(AuthUrlGetReq req) {
        AuthRequest authRequest = getAuthRequest(req.getClient(), req.getBackUrl());
        String url = authRequest.authorize(AuthStateUtils.createState());

        return ThirdAuthResp.builder().pageUrl(url).build();
    }
}
